home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_2
/
wiconify
/
wiconsetter.lzh
/
wIconSetter
/
Source
/
wIconFileRead.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
11KB
|
397 lines
/*
* WICONSETTER A companion utility to wIconify. wIconSetter allows
* you to specify custom icons for windows ans screens
* that normally use the default icons.
*
* wIconFileRead.c Reads the initialization file.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#include "wIconFile.h"
UWORD ImageData[MAXWORDS][MAXHEIGHT][MAXDEPTH];
short MaxWidth,MaxHeight,MaxWords;
UBYTE Plane0,Plane1;
int ImageType;
int IconFileOpen;
short BitMapLine;
static int NoMaskError; /* FALSE if a mask error was reported */
static short ErrorCount; /* number of error messages so far */
#define MAXERROR 8 /* maximum number of errors in a line */
/*
* Allowable HEX codes
*/
static char *ExtHex = "0123456789abcdef)!@#$%^&*(ABCDEF";
/*
* The initialization file command keywords
*/
static char *MainCommand[] =
{
"",
"Program", /* Specifies Program name for this icon */
"Screen", /* Specifies Screen name for this icon */
"Window", /* SPecified window name for this icon */
"Icon", /* Uses a DEFINEd icon, or read icon from file */
"Image", /* Sets icon image */
"Select", /* Sets icon select image */
"Mask", /* Sets icon mask */
"Flags", /* Sets the icon's flags */
"Position", /* Sets initial position of icon */
"Name", /* Sets icon's name when iconified */
"Define", /* Defines an icon to be used more than once */
};
#define MAXMAINCOM COM_LAST
/*
* The commands for within an icon file (ICON: FROM commands)
*/
static char *IconCommand[] =
{
"Image",
"Select",
"Mask",
"Flags",
"Position",
"Name"
};
#define MAXICONCOM 5
char **ComName = &MainCommand[0]; /* The current command set */
static int ComOffset; /* Add this to get "real" command # */
static int ComCount = MAXMAINCOM; /* Size of command array */
/*
* Icon Flags for FLAGS command
*/
static struct Flag IconFlag[] =
{
{"NOICONIFY", WI_NOICONIFY}, /* Window can not be iconified */
{"NOSAVEPOS", WI_NOSAVEPOS}, /* Position not saved when openned */
{"NOCLOSE", WI_NOCLOSE}, /* CLOSE menu not available */
{"NOORGANIZE", WI_NOORGANIZE}, /* Icon not affected by ORGANIZE */
{"NOMOVE", WI_NOMOVE}, /* Icon can not be moved */
{"LOCKED", WI_LOCKED}, /* Never change icon X,Y */
{"NOMULTISELECT",WI_NOMULTISELECT}, /* No more than one icon selectable */
{"CHANGEREFRESH",WI_CHANGEREFRESH}, /* Automatically change refresh type */
{"AUTOICONIFY", WI_AUTOICONIFY}, /* Iconify window as it opens */
};
#define MAXICONFLAG 9
/*
* ReadCommand()
*
* If we're at the end of the line, read the next line.
* Get the next word on the line.
* If we have readed the end of the file, use COM_EOF
* Otherwise, if the character following the next word is not ':'
* then we have not found a command, so use COM_NONE,
* Otherwise,
* Look for the command in the current command table, and skip the ':'
* Return the number of the command found.
*/
int ReadCommand()
{
int Command = COM_UNKNOWN;
short i;
if (NextChar == '\n' || NextChar == 0) ReadNextLine();
ReadNextWord();
if (EndOfFile) Command = COM_EOF; else
if (NextChar != ':') Command = COM_NONE;
else
{
for (i=0; i<=ComCount && Command == COM_UNKNOWN; i++)
if (WORDMATCH(ComName[i])) Command = i + ComOffset;
SkipChar();
}
return(Command);
}
/*
* ReadIconFlags()
*
* If the word is '+' or '|', then
* If there were no previous flags specified, give an error
* The next word is the flag name
* Look through the flag names
* If one of them matches,
* Add the flag to the default flags and end the loop
* If no flag found, give an error.
*/
void ReadIconFlags(theFlags)
ULONG *theFlags;
{
short i;
if (Word[0] == '|' || Word[0] == '+')
{
if (*theFlags == 0)
ShowError("Missing Icon Flag before '%c'",Word[0]);
ReadNextWord();
}
for (i=0; i<MAXICONFLAG; i++)
{
if (WORDMATCH(IconFlag[i].Name))
*theFlags |= IconFlag[i].Flag,
i = MAXICONFLAG+1;
}
if (i == MAXICONFLAG) Expected("an Icon Flag");
}
/*
* ReadInteger()
*
* Parse the next word as an integer.
* If the word is an integer, return it, otherwise give an error.
*/
void ReadInteger(i)
int *i;
{
ReadNextInteger();
if (sscanf(Word,"%d",i) != 1) Expected("an Integer value");
}
/*
* ReadPosition()
*
* Start reading this data again.
* If the word begins with a '(',
* Skip it and read the x-position.
* If the next char is a comma,
* Skip it an read the y-position.
* If the next character is a ')'
* Skip it and save the position values if they are OK.
* Otherwise, show an appropriate error.
*/
void ReadPosition(x,y)
WORD *x,*y;
{
int X = *x,
Y = *y;
Reread();
if (NextChar == '(')
{
ReadNextChar(); ReadInteger(&X);
if (NextChar == ',')
{
ReadNextChar(); ReadInteger(&Y);
if (NextChar == ')')
{
ReadNextChar();
if (X > 0 && Y > 0) *x = X, *y = Y;
} else Expected(")"), NextChar = '\n';
} else Expected(","), NextChar = '\n';
} else Expected("an (x,y) position"), NextChar = '\n';
}
/*
* CopyName()
*
* If we can allocate space for the name, copy it,
* Otherwise, show an error.
*/
void CopyName(s,Name)
char **s;
char *Name;
{
if (NEWCHAR(*s,strlen(Name))) strcpy(*s,Name);
else ShowError("Can't get memory for character string");
}
/*
* ReadName()
*
* Get the rest of the input line
* If a name string already exists, free it
* If the name is [ANY] or [NULL], set the special values,
* Otherwise copy the new name to the name string.
*/
void ReadName(name)
char **name;
{
ReadFullLine();
if (*name != NAME_NULL && *name != NAME_ANY) FREECHAR(*name);
if (WORDMATCH("[ANY]")) *name = NAME_ANY; else
if (WORDMATCH("[NULL]")) *name = NAME_NULL; else
CopyName(name,Word);
}
/*
* GetPen()
*
* Look for the given HEX digit in the extended HEX list.
* If not found,
* Give an error message and count the number of errors.
* If more than the maximum allowed, skip the rest of the line.
* If the image type is a MASK, and the pen is not 0 or 1,
* If there were no previous errors of this type, give one.
* Mark that the user was warned about mask pen types.
* Reduce the pen number to 0 or 1.
* Return the pen color.
*/
static UBYTE GetPen(c)
char c;
{
UBYTE Pen = 0;
short i;
for (i=0; i<32; i++) if (c == ExtHex[i]) Pen = i, i = 33;
if (i == 32)
{
Expected("HEX Digit"); ErrorCount++;
if (ErrorCount > MAXERROR)
printf("Maximum errors exceeded - skipping rest of line\n"),
SkipLine();
}
if (Pen > 1 && ImageType == COM_MASK)
{
if (NoMaskError) ShowError("Mask pixel values must be 0 or 1");
NoMaskError = FALSE;
Pen = Pen & 1;
}
return(Pen);
}
/*
* ReadImageLine()
*
* If the current line is within the maximum image size,
* Clear the error flags, and get back to the beginning of the line.
* While we're not at the end of the line,
* If the current column is within the maximum image size,
* Get the pen number of the current pixel, and increment the column.
* Update Plane0 and Plane1 (Plane0 has a zero wherever that plane
* has at least one pixel that is zero; Plane1 has a 1 wherever
* that plane has at least one pixel that is one).
* If the bit mask has wrapped around, go on to the next image word.
* For each 1 bit in the Pen color, add a 1 bit into the image data
* Shift the image mask to the right.
* Get the next pixel's pen color and skip any comments.
* Skip trailing blanks (but not interior blanks).
* Otherwise, indicate that the width is too large and skip to the
* end of the line.
* Update the current image size, if necessary.
* Otherwise, indicate that the icon is too tall, and skip to the next line.
*/
void ReadImageLine(y)
short y;
{
short x = 0, w = 0;
short d;
UWORD mask = BIT(15);
UBYTE Pen;
if (y < MAXHEIGHT)
{
NoMaskError = TRUE; ErrorCount = 0;
Reread();
while (NextChar != '\n')
{
if (x < MAXWIDTH)
{
Pen = GetPen(NextChar); x++;
Plane0 &= Pen; Plane1 |= Pen; d = 0;
if (mask == 0) w++, mask = BIT(15);
while (Pen)
{
if (Pen & 1) ImageData[w][y][d] |= mask;
Pen >>= 1; d++;
}
mask >>= 1;
GetNextChar(); SkipComments();
if (NextChar == ' ')
{
SkipSpaces();
if (NextChar != '\n') Reread();
}
} else {
ReadFullLine();
ShowError("Maximum Image Width of %d exceeded",MAXWIDTH);
}
}
if (x > MaxWidth) MaxWidth = x, MaxWords = w+1;
if (y+1 > MaxHeight) MaxHeight = y+1;
if (MaxWidth > MAXWIDTH) MaxWidth = MAXWIDTH;
} else {
ReadFullLine();
ShowError("Maxmimum Image Height of %d exceeded",MAXHEIGHT);
}
}
/*
* ReadIconFile()
*
* Get the rest of the line (it will be the file name to open)
* Save the current file information.
* Attempt to open the specified file.
* If openned OK, then
* Set the icon file flag,
* Set the command list to the icon file command list and size.
* Otherwise,
* Put back the old file information,
* Give an error about the icon file.
*/
void ReadIconFile()
{
ReadFullLine();
SaveOpenFile();
if (OpenFile(Word))
{
IconFileOpen = TRUE;
ComName = &IconCommand[0];
ComOffset = COM_IMAGE;
ComCount = MAXICONCOM;
} else {
RestoreFile();
ShowError("Can't open Icon file '%s'",Word);
}
}
/*
* EndIconFile()
*
* Put back the old file information
* Mark the file as closed, and restore the command list to the main list.
*/
void EndIconFile()
{
RestoreFile();
IconFileOpen = FALSE;
ComName = &MainCommand[0];
ComOffset = 0;
ComCount = MAXMAINCOM;
}